package com.cci.kangdao.fieldService.aop;

import com.cci.kangdao.aop.UserThreadLocal;
import com.cci.kangdao.common.type.NotifyChannelType;
import com.cci.kangdao.common.type.NotifyModelType;
import com.cci.kangdao.crmapi.CRMServiceConst;
import com.cci.kangdao.dao.model.UserT;
import com.cci.kangdao.escalation.aop.model.EscalationThreadLocal;
import com.cci.kangdao.fieldService.aop.model.CFWOThreadLocal;
import com.cci.kangdao.fieldService.aop.model.ChannelThreadLocal;
import com.cci.kangdao.aop.RequestBodyThreadLocal;
import com.cci.kangdao.fieldService.dto.request.CCGRequest;
import com.cci.kangdao.fieldService.service.FieldServiceChannelService;
import com.cci.kangdao.service.NotifyConfigService;
import com.cci.kangdao.utilTool.JsonUtils;
import com.cci.kangdao.utilTool.NumberUtils;
import com.cci.kangdao.utilTool.ParameterTool;
import com.cci.kangdao.utilTool.PublicTool;
import com.cci.kangdao.utilTool.RequestContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author William Du
 * @date 2019/12/30
 */
@Component
@Aspect
@Order(Ordered.HIGHEST_PRECEDENCE+1)
public class FieldServiceIntercept {

    private static final Logger logger = Logger.getLogger(FieldServiceIntercept.class);

    @Resource
    private FieldServiceChannelService fieldServiceChannelService;

    @Resource
    private NotifyConfigService notifyConfigService;

    /**
     * CRM同步APP接口的拦截器
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(* com.cci.kangdao.fieldService.controller.CCGSyncController.*(..)) && @within(org.springframework.stereotype.Controller)")
    public Object aroundCCG(ProceedingJoinPoint proceedingJoinPoint) {
        try {
            String requestString = RequestBodyThreadLocal.get();
            if (StringUtils.isNotEmpty(requestString)) {
                Object response = null;
                CCGRequest request = JsonUtils.toJavaObject(requestString,CCGRequest.class);
                // 通过传输的渠道编号，获取渠道ID
                Long channel = fieldServiceChannelService.getChannel(request.getChannel());
                if(null == channel){
                    ParameterTool.writeResponse(RequestContextHolder.getResponse(),1,"不存在对应渠道配置，请检查channel参数");
                    return null;
                }else {
                    // 将渠道信息放入ThreadLocal
                    ChannelThreadLocal.set(channel);
                }
                // 判断基本信息和token
                Boolean validate = baseFilter(request);
                if (!validate) {
                    ParameterTool.writeResponse(RequestContextHolder.getResponse(),-99,"请求验证失败，请检查请求信息");
                    return null;
                }
                return proceedingJoinPoint.proceed();
            }
        } catch (Throwable throwable) {
            logger.error(throwable.getMessage(), throwable);
            ParameterTool.writeErrorResponse(RequestContextHolder.getResponse());
        }finally {
            //清除ThreadLocal值，防止异常线程调用
            ChannelThreadLocal.clear();
        }
        return null;
    }

    /**
     * APP后台接口拦截器
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(* com.cci.kangdao.fieldService.controller.FieldServiceController.*(..)) && @within(org.springframework.stereotype.Controller)")
    public Object aroundBusiness(ProceedingJoinPoint proceedingJoinPoint) {
        try {
            UserT userT = UserThreadLocal.get();
            // 通过用户信息获取渠道
            Long channel = fieldServiceChannelService.getChannel(userT);
            if(!NumberUtils.isPositiveNum(channel)){
                ParameterTool.writeResponse(RequestContextHolder.getResponse(),-99,"未获取到用户对应渠道数据，请检查配置信息");
                return null;
            }
            ChannelThreadLocal.set(channel);
            return proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            logger.error(throwable.getMessage(), throwable);
            ParameterTool.writeErrorResponse(RequestContextHolder.getResponse());
            return null;
        }finally {
            //清除ThreadLocal值，防止异常线程调用
            ChannelThreadLocal.clear();
        }
    }

    private Boolean baseFilter(CCGRequest ccgRequest) {
        try {
            String token = RequestContextHolder.getHeader("token");
            // 验证token是否对应
            if (CRMServiceConst.IS_CRMHEADER_ADDMD5) {
                // 查看必填参数是否为空
                if (StringUtils.isEmpty(token) || StringUtils.isEmpty(ccgRequest.getChannel()) || StringUtils.isEmpty(ccgRequest.getSystemTime())) {
                    return Boolean.FALSE;
                }
                // 三者皆不为空，并且计算token是否一致。
                if (StringUtils.isNotEmpty(token) && StringUtils.isNotEmpty(ccgRequest.getChannel()) && StringUtils.isNotEmpty(ccgRequest.getSystemTime())) {
                    String md5ToToken = PublicTool.compute(String.format("%s+%s", ccgRequest.getChannel(), ccgRequest.getSystemTime()));
                    if (!token.equals(md5ToToken)) {
                        return Boolean.FALSE;
                    }
                } else {
                    return Boolean.FALSE;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}
